package com.car.loan.project.xr.util.repayment.impl;

import com.alibaba.fastjson.JSON;
import com.car.loan.project.xr.util.repayment.RepaymentFormulaInterface;
import com.car.loan.project.xr.util.repayment.RepaymentInfo;
import com.car.loan.project.xr.util.repayment.RepaymentInfoParam;
import com.car.loan.project.xr.util.repayment.RepaymentPlan;
import com.car.loan.project.xr.util.repayment.RepaymentPlanParam;
import com.car.loan.project.xr.util.repayment.RepaymentPlanUtil;
import java.math.BigDecimal;
import java.math.MathContext;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;

/**
 * @author huangding
 * @description 中国银行还款公式
 * @date 2019/12/31 9:35
 */
@Service("bocRepaymentFormula")
public class BocRepaymentFormula implements RepaymentFormulaInterface {


    /**
     * A=融资金额 B=分期金额 C=分期期数 D=银行基础费率 每月本金=末月本金=取整（B/C）+取整（（A-B）/C） 首月本金=A-每月本金*（C-1）
     * 每个月的利息=相应月的本金*D，保留二位小数，后面有余数的向上进1
     *
     * @param repaymentInfoParam 还款信息参数
     */
    @Override
    public RepaymentInfo getRepaymentInfo(RepaymentInfoParam repaymentInfoParam) {

        //融资金额
        BigDecimal a = repaymentInfoParam.getFinancingAmount();
        //B=分期金额
        BigDecimal b = repaymentInfoParam.getInstallmentAmount();
        //C=分期期数
        BigDecimal c = new BigDecimal(repaymentInfoParam.getTerm());
        //D=银行基础费率
        BigDecimal d = repaymentInfoParam.getRate();

        //每月本金=末月本金=取整（B/C）+取整（（A-B）/C）
        BigDecimal monthRepayPrincipal, lastRepayPrincipal;
        lastRepayPrincipal = monthRepayPrincipal = b.divide(c, MathContext.DECIMAL128)
            .setScale(0, BigDecimal.ROUND_DOWN)
            .add((a.subtract(b)).divide(c, MathContext.DECIMAL128)
                .setScale(0, BigDecimal.ROUND_DOWN));
        // 首月本金=A-每月本金*（C-1）
        BigDecimal firstRepayPrincipal = a.subtract(
            monthRepayPrincipal.multiply(new BigDecimal(repaymentInfoParam.getTerm() - 1)))
            .setScale(6, BigDecimal.ROUND_HALF_UP)
            .setScale(0, BigDecimal.ROUND_CEILING);

        //每个月的利息=相应月的本金*D，保留二位小数，后面有余数的向上进1
        BigDecimal monthRepayInterest, lastRepayInterest;
        lastRepayInterest = monthRepayInterest = monthRepayPrincipal.multiply(d)
            .setScale(2, BigDecimal.ROUND_HALF_UP);

        BigDecimal firstRepayInterest = firstRepayPrincipal.multiply(d)
            .setScale(2, BigDecimal.ROUND_HALF_UP);

        RepaymentInfo repaymentInfo = new RepaymentInfo();
        repaymentInfo.setMonthRepayInterest(monthRepayInterest);
        repaymentInfo.setMonthRepayPrincipal(monthRepayPrincipal);
        repaymentInfo.setFirstRepayInterest(firstRepayInterest);
        repaymentInfo.setFirstRepayPrincipal(firstRepayPrincipal);
        repaymentInfo.setLastRepayInterest(lastRepayInterest);
        repaymentInfo.setLastRepayPrincipal(lastRepayPrincipal);
        repaymentInfo.setFirstStatementDate(RepaymentPlanUtil
            .getFirstStatementDate(repaymentInfoParam.getLendDate(),
                repaymentInfoParam.getStatementDay()));
        return repaymentInfo;
    }

    @Override
    public Integer getFinancingAmount(BigDecimal installmentAmount, BigDecimal rate,
        BigDecimal bankRate) {
        rate = rate.divide(new BigDecimal(100), MathContext.DECIMAL128);
        bankRate = bankRate.divide(new BigDecimal(100), MathContext.DECIMAL128);
        BigDecimal add = BigDecimal.ONE.add(rate.subtract(bankRate, MathContext.DECIMAL128));
        //分期金额*（1+（执行费率—银行基础费率））注意百分比，算出来的金额如是中国银行的业务向上进1保留到个位（如56789.01进为56790，56789还是进为56789），
        return installmentAmount.multiply(add, MathContext.DECIMAL128)
            .setScale(2, BigDecimal.ROUND_HALF_UP)
            .setScale(0, BigDecimal.ROUND_UP).intValue();
    }

    @Override
    public Integer getMiniBillingAmount(Integer financingAmount, BigDecimal installmentAmount,
        Integer carType) {
        if (carType == 1) {
            return installmentAmount.divide(new BigDecimal(0.8), MathContext.DECIMAL128)
                .setScale(6, BigDecimal.ROUND_HALF_UP)
                .setScale(-2, BigDecimal.ROUND_CEILING ).intValue();
        } else if (carType == 2) {
            return installmentAmount.divide(new BigDecimal(0.7), MathContext.DECIMAL128)
                .setScale(6, BigDecimal.ROUND_HALF_UP)
                .setScale(-2, BigDecimal.ROUND_CEILING ).intValue();
        } else {
            throw new UnsupportedOperationException("未实现");
        }
    }

    public static void main(String[] args) {

        System.out.println(new BigDecimal("56789.01").setScale(-2, BigDecimal.ROUND_FLOOR)
            .setScale(0, BigDecimal.ROUND_UP).intValue());

        BocRepaymentFormula abcRepaymentFormula = new BocRepaymentFormula();

        Integer miniBillingAmount = abcRepaymentFormula
            .getMiniBillingAmount(0, new BigDecimal(79000), 2);
        System.out.println(miniBillingAmount);

        RepaymentInfoParam repaymentInfoParam = new RepaymentInfoParam();
        repaymentInfoParam.setLendDate("2019-10-28");
        repaymentInfoParam.setStatementDay(28);
        repaymentInfoParam.setFinancingAmount(new BigDecimal(52900));
        repaymentInfoParam.setInstallmentAmount(new BigDecimal(50000));
        repaymentInfoParam.setRate(new BigDecimal(0.082));
        repaymentInfoParam.setTerm(36);
        repaymentInfoParam.setGracePeriod(28);
        RepaymentInfo repaymentInfo = abcRepaymentFormula.getRepaymentInfo(repaymentInfoParam);
        System.out.println(JSON.toJSONString(repaymentInfo));

        System.out.println(
            "中行：分期金额=" + repaymentInfoParam.getFinancingAmount() + " ；融资金额=" + repaymentInfoParam
                .getInstallmentAmount() + "；费率=0.082；期数="
                + repaymentInfoParam.getTerm() + "；结果：首月利息=" + repaymentInfo.getFirstRepayInterest()
                + ",首月本金=" + repaymentInfo.getFirstRepayPrincipal() + ", 每月利息=" + repaymentInfo
                .getMonthRepayInterest()
                + ",每月本金=" + repaymentInfo.getMonthRepayPrincipal() + "末月利息=" + repaymentInfo
                .getLastRepayInterest()
                + ",末月本金=" + repaymentInfo.getLastRepayPrincipal());

        RepaymentPlanParam repaymentPlanParam = new RepaymentPlanParam();
        repaymentPlanParam.setMonthRepayInterest(repaymentInfo.getMonthRepayInterest());
        repaymentPlanParam.setMonthRepayPrincipal(repaymentInfo.getMonthRepayPrincipal());
        repaymentPlanParam.setFirstRepayInterest(repaymentInfo.getFirstRepayInterest());
        repaymentPlanParam.setFirstRepayPrincipal(repaymentInfo.getFirstRepayPrincipal());
        repaymentPlanParam.setLastRepayInterest(repaymentInfo.getLastRepayInterest());
        repaymentPlanParam.setFinancingAmount(repaymentInfoParam.getFinancingAmount());
        repaymentPlanParam.setLastRepayPrincipal(repaymentInfo.getLastRepayPrincipal());

        repaymentPlanParam.setFirstStatementDate(repaymentInfo.getFirstStatementDate());
        repaymentPlanParam.setGracePeriod(28);
        repaymentPlanParam.setTerm(36);

        List<RepaymentPlan> repaymentPlans = abcRepaymentFormula
            .getRepaymentPlans(repaymentPlanParam);
        System.out.println(JSON.toJSONString(repaymentPlans));

    }
}
